// console.log('wzg111');
// console.log(hi);
// 继承
(function () {
  class Person {
    // 对象属性，通过对象访问  readonly,只读属性
    name: string;
    age: number;
    // 类属性---静态属性，通过类访问
    static abc: number = 12;
    constructor(name: string, age: number) {
      this.name = name;
      this.age = age;
    }

    getName(): string {
      return this.name;
    }

    setName(name: string) {
      this.name = name;
    }

    setAge(age: number) {
      this.age = age;
    }
  }

  let person = new Person('wzg', 18);
  console.log(person.getName());
  person.setName('gg');
  console.log(Person.abc);

  console.log(person.getName());
  console.log(person);

  // 抽象类，不能创建实例对象
  // 当不希望这个类用来创建对象的时候，可以使用abstract关键字来声明一个类为抽象类
  // 抽象类中，可以声明抽象方法
  abstract class Animal {
    protected name: string;
    constructor(name: string) {
      this.name = name;
    }

    // 定义抽象方法
    abstract sayHello(): void;
  }

  class Dog extends Animal {
    // private age: number;
    constructor(protected name: string, private age: number) {
      // 执行 父类的构造函数
      // 如果在子类中写了构造函数，
      // 在子类构造函数中必须对父类构造函数进行调用
      super(name);
      this.age = age;
    }

    sayHello(): void {
      console.log(this.age);
    }

    getAge(): number {
      return this.age;
    }
    setAge(age: number): void {
      this.age = age;
    }
  }

  const dog = new Dog('狗', 10);
  dog.sayHello();
  // dog.age = 10;
  // dog.setAge(13);
  console.log(dog.getAge());
})();

// 接口
(function () {
  type myTYpe = {
    name: string;
    age: number;
  };
  const obj: myTYpe = {
    name: 'q',
    age: 123,
  };

  // 接口用来定义一个类结构,用于定义一个规范，对类的限制
  interface myInterface {
    name: string;
    age: number;
  }
  interface myInterface {
    name: string;
    age: number;
    gender: string;
    sayHello(): void;
  }

  // const obj1: myInterface = {
  //   name: 'qweq',
  //   age: 222,
  //   gender: '男',
  // };

  class MyClass implements myInterface {
    name: string;
    age: number;
    gender: string;
    constructor(name: string, age: number, gender: string) {
      this.name = name;
      this.age = age;
      this.gender = gender;
    }
    sayHello(): void {}
  }
})();

// 泛型
(function () {
  function fn<T>(a: T): T {
    return a;
  }

  let aa = fn<number>(1111);
  console.log(aa);
  let str = fn<string>('wzg');
  console.log(str);

  function fn2<T, K>(a: T, b: K): T {
    return a;
  }

  interface Inter {
    length: number;
  }

  //泛型约束
  // T extends Inter 表示泛型T必须是Inter的实现类（子类）
  function fn3<T extends Inter>(a: T) {
    return a.length;
  }

  // fn3(123);
  fn3({ a: 1, length: 19 });

  class MyClass<T> {
    constructor(public name: T) {
      this.name = name;
    }
  }

  let aaa = new MyClass<string>('12');
  console.log(aaa.name);
})();
